#include <stdio.h>
#include <getopt.h>

#include "../util.h"
#include "../verb/onlineinfo.h"
#include "../action/onlineinfo.h"

_Noreturn void verb_onlineinfo_usage(FILE *restrict out) {
    fputs("Usage: " PROGRAM_NAME " onlineinfo [OPTIONS]\n", out);
    fputs("Fetch the online infomation.\n", out);
    fputs("Host is required.\n", out);
    fputs("\n", out);
    fputs("Options:\n", out);
    fputs("  -i, --user-index USERINDEX specify the USER INEDX\n", out);
    fputs("  --help                     display this help and exit\n", out);
    fputs("\n", out);
    fputs("Exit status:\n", out);
    fputs(" 0  if successfully fetched and parsed\n", out);
    fputs(" 1  if unable to parse arguments\n", out);
    fputs(" 2  if unable to fetch infomation\n", out);
    fputs(" 3  if unable to parse infomation\n", out);
    exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}

int verb_onlineinfo(const int argc, char* const* argv) {
    int lose = 0;
    static struct option long_options[] = {
        {"user-index",  required_argument,  NULL, 'i' },
        {"help",        no_argument,        NULL, 'h' },
        {0,             0,                  0,     0 }
    };
    const char* user_index = NULL;
    
    while (1) {
        int c = getopt_long(argc, argv, "i:h", long_options, NULL);

        if (c == -1) {
            break;
        }

        switch (c) {
            case 'i':
                if (user_index != NULL) {
                    error(0, 0, "exceed argument: %s", optarg);
                    verb_onlineinfo_usage(stderr);
                }
                user_index = optarg;
                break;
        
            case 'h':
                verb_onlineinfo_usage(stdout);
                break;

            default:
                lose = 1;
                break;
        }
    }
    
    if (lose) {
        verb_onlineinfo_usage(stderr);
        exit(EXIT_FAILURE);
    }
    
    if (optind < argc) {
        error(0, 0, "Too many arguments.\n");
        verb_onlineinfo_usage(stderr);
        exit(EXIT_FAILURE);
    }
    
    if (GLOBAL_ARGS.portal_host == NULL) {
        error(0, 0, "No host provided.");
        exit(EXIT_FAILURE);
    }
    
    action_onlineinfo_result result = action_onlineinfo(
        GLOBAL_ARGS.bind_interface,
        GLOBAL_ARGS.portal_host,
        user_index
    );
    
    if (result.status == ACTION_FETCHING_FAILURE) {
        return 2;
    }
    
    if (result.status == ACTION_PARSE_FAILURE) {
        return 3;
    }
    
    if (result.return_status == SUCCESS) {
        puts("Status: success");
        printf("Message: %s\n", result.message);
        printf("UserId: %s\n", result.user_id);
        printf("UserName: %s\n", result.user_name);
        printf("UserIp: %s\n", result.user_ip);
        printf("UserMac: %s\n", result.user_mac);
        printf("UserPackage: %s\n", result.user_package);
        printf("UserIndex: %s\n", result.user_index);
    } else if (result.return_status == WAIT) {
        puts("Status: wait");
        printf("Message: %s\n", result.message);
    } else if (result.return_status == FAILED) {
        puts("Status: failed");
        printf("Message: %s\n", result.message);
    }
    
    return 0;
}
